package com.woniu34.search.service.impl;

import com.woniu.cinema.api.CinemaFeignApi;
import com.woniu.cinema.domain.Actor;
import com.woniu.cinema.domain.MovieActor;
import com.woniu.cinema.vo.MovieVo;
import com.woniu.common.constant.Constants;
import com.woniu34.search.domain.ActorSearch;
import com.woniu34.search.domain.CinemaSearch;
import com.woniu34.search.domain.MovieSearch;
import com.woniu34.search.repository.ActorRepository;
import com.woniu34.search.repository.CinemaRepository;
import com.woniu34.search.repository.MovieRepository;
import com.woniu34.search.service.SearchService;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SearchServiceImpl implements SearchService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private CinemaFeignApi cinemaFeignApi;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;


    @Autowired
    private CinemaRepository cinemaRepository;

    @Autowired
    private ActorRepository actorRepository;

    @Autowired
    private MovieRepository movieRepository;


    @Override
    @PostConstruct
    public void initEs() {
        deleteIndex();
        createIndex();
        //查询电影院列表
        List<CinemaSearch> cinemaSearchList = cinemaFeignApi.listAllCinema(-1L)
                .stream().map(cinema -> {
                    CinemaSearch cinemaSearch = new CinemaSearch();
                    BeanUtils.copyProperties(cinema, cinemaSearch);
                    return cinemaSearch;
                }).collect(Collectors.toList());

        for (CinemaSearch cinemaSearch : cinemaSearchList) {
            cinemaRepository.save(cinemaSearch);
        }
        //查询演员列表
        List<ActorSearch> actorSearchList = cinemaFeignApi.listAllActor(-1L).stream().map(actor -> {
            ActorSearch actorSearch = new ActorSearch();
            BeanUtils.copyProperties(actor, actorSearch);
            return actorSearch;
        }).collect(Collectors.toList());


        List<MovieSearch> movieSearchList = cinemaFeignApi.listAllMovie(-1L).stream().map(m -> {
            MovieSearch movieSearch = new MovieSearch();
            BeanUtils.copyProperties(m, movieSearch);
            movieSearch.setMovieAreaStr(m.getMovieAreaStr());//把首映地区设置一下
            movieSearch.setMovieTypeStr(m.getMovieTypeStr());
            movieSearch.setAllText(movieSearch.getMovieEname() + " " + movieSearch.getMovieName() + " " + movieSearch.getMovieInfo());
            return movieSearch;
        }).collect(Collectors.toList());

        for (MovieSearch movieSearch : movieSearchList) {
            movieRepository.save(movieSearch);
        }

        //把movieSearch列表转成map，key：movieId，value：movieName
        Map<Long, String> movieMap = movieSearchList.stream()
                .collect(Collectors.toMap(MovieSearch::getMovieId, MovieSearch::getMovieName));


        List<MovieActor> movieActors = cinemaFeignApi.listAllMovieActor();

        for (ActorSearch actorSearch : actorSearchList) {
            StringBuilder movies = new StringBuilder();
            for (MovieActor movieActor : movieActors) {
                if(actorSearch.getActorId()==movieActor.getActorId()){
                    String movieName = movieMap.get(movieActor.getMovieId());
                    if(movieName!=null){
                        movies.append("《"+movieName+"》").append(" ");
                    }

                }
            }
            actorSearch.setMovieNames("代表作："+movies.toString());

            actorRepository.save(actorSearch);
        }


    }

    @Override
    public Page<CinemaSearch> queryCinemaList(String searchKey) {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(QueryBuilders.matchQuery("cinemaName",searchKey));
        Page<CinemaSearch> results = cinemaRepository.search(queryBuilder.build());
        System.out.println(results);

        return results;

    }

    @Override
    public Page<ActorSearch> queryActorList(String searchKey) {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(QueryBuilders.matchQuery("actorName",searchKey));
        Page<ActorSearch> results = actorRepository.search(queryBuilder.build());
        System.out.println(results);

        return results;

    }

    @Override
    public Page<MovieSearch> queryMovieList(String searchKey) {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withQuery(QueryBuilders.matchQuery("allText",searchKey));
        Page<MovieSearch> results = movieRepository.search(queryBuilder.build());
        System.out.println(results);

        return results;

    }

    private void createIndex(){
        elasticsearchTemplate.createIndex(CinemaSearch.class);
        elasticsearchTemplate.putMapping(CinemaSearch.class);
        elasticsearchTemplate.createIndex(ActorSearch.class);
        elasticsearchTemplate.putMapping(ActorSearch.class);
        elasticsearchTemplate.createIndex(MovieSearch.class);
        elasticsearchTemplate.putMapping(MovieSearch.class);
    }
    private void deleteIndex(){
        elasticsearchTemplate.deleteIndex(CinemaSearch.class);
        elasticsearchTemplate.deleteIndex(ActorSearch.class);
        elasticsearchTemplate.deleteIndex(MovieSearch.class);
    }

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(name = Constants.MQ_ES_MOVIE_QUEUE_NAME),
                    exchange = @Exchange(name = Constants.MQ_ES_EXCHANGE_NAME),
                    key = {Constants.MQ_ES_UPDATE_MOVIE_ROUTING_KEY}
            )
    })
    public void updateMovie(Map<String,Long> msg){
        Long id = msg.get("id");
        List<MovieSearch> movieSearchList = cinemaFeignApi.listAllMovie(id).stream().map(m -> {
            MovieSearch movieSearch = new MovieSearch();
            BeanUtils.copyProperties(m, movieSearch);
            movieSearch.setMovieAreaStr(m.getMovieAreaStr());//把首映地区设置一下
            movieSearch.setMovieTypeStr(m.getMovieTypeStr());
            movieSearch.setAllText(movieSearch.getMovieEname() + " " + movieSearch.getMovieName() + " " + movieSearch.getMovieInfo());
            return movieSearch;
        }).collect(Collectors.toList());

        for (MovieSearch movieSearch : movieSearchList) {
            movieRepository.save(movieSearch);
        }
    }



    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(name = Constants.MQ_ES_CINEMA_QUEUE_NAME),
                    exchange = @Exchange(name = Constants.MQ_ES_EXCHANGE_NAME),
                    key = {Constants.MQ_ES_UPDATE_CINEMA_ROUTING_KEY}
            )
    })
    public void updateCinema(Map<String,Long> msg){
        Long id = msg.get("id");
        List<CinemaSearch> cinemaSearchList = cinemaFeignApi.listAllCinema(id)
                .stream().map(cinema -> {
                    CinemaSearch cinemaSearch = new CinemaSearch();
                    BeanUtils.copyProperties(cinema, cinemaSearch);
                    return cinemaSearch;
                }).collect(Collectors.toList());

        for (CinemaSearch cinemaSearch : cinemaSearchList) {
            cinemaRepository.save(cinemaSearch);
        }
    }


    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(name = Constants.MQ_ES_CINEMA_QUEUE_NAME),
                    exchange = @Exchange(name = Constants.MQ_ES_EXCHANGE_NAME),
                    key = {Constants.MQ_ES_UPDATE_CINEMA_ROUTING_KEY}
            )
    })
    public void updateActor(Map<String,Long> msg){
        Long id = msg.get("id");

        //查询演员列表
        List<ActorSearch> actorSearchList = cinemaFeignApi.listAllActor(id).stream().map(actor -> {
            ActorSearch actorSearch = new ActorSearch();
            BeanUtils.copyProperties(actor, actorSearch);
            return actorSearch;
        }).collect(Collectors.toList());

        List<MovieActor> movieActors = cinemaFeignApi.listAllMovieActor();

        for (ActorSearch actorSearch : actorSearchList) {
            StringBuilder movies = new StringBuilder();
            for (MovieActor movieActor : movieActors) {
                if(actorSearch.getActorId()==movieActor.getActorId()){
                    List<MovieVo> movieVos = cinemaFeignApi.listAllMovie(movieActor.getMovieId());
                    String movieName =movieVos.get(0).getMovieName();
                    if(movieName!=null){
                        movies.append("《"+movieName+"》").append(" ");
                    }

                }
            }
            actorSearch.setMovieNames("代表作："+movies.toString());

            actorRepository.save(actorSearch);
        }
    }
}
